package org.elanfox.intellicommunity.msg.server.handler;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.elanfox.intellicommunity.msg.ienum.CmdEnums;
import org.elanfox.intellicommunity.msg.server.base.MsgChannelRegister;
import org.elanfox.intellicommunity.msg.server.service.CmdNormalReader;
import org.elanfox.intellicommunity.msg.server.service.CmdReaderBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author allan
 * @version 1.0.0
 * @date 2019/12/11
 */
@Component
@ChannelHandler.Sharable
@Slf4j
public class MsgServerHandler extends ChannelInboundHandlerAdapter {
    @Autowired
    private CmdReaderBuilder cmdReaderBuilder;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //解析
        ByteBuf in = (ByteBuf) msg;
        String hexStr = ByteBufUtil.hexDump(in);
        in.release();

        //read
        CmdEnums.Code cmdCode = cmdReaderBuilder.cmdCode(hexStr);
        if (cmdCode != null) {
            //时间应答特殊处理，只有应答了，通道才算注册成功
            if (cmdCode == CmdEnums.Code.TIME_VERIFY) {
                CmdNormalReader cmdNormalReader = (CmdNormalReader) cmdReaderBuilder.build(cmdCode);
                cmdNormalReader.timeVerify(hexStr, ctx.channel());
            } else {
                cmdReaderBuilder.build(cmdCode).read(cmdCode, hexStr);
            }
        }
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) {
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) {
        MsgChannelRegister.remove(ctx.channel());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error("channel error====>" + ctx.channel().id(), cause);
        MsgChannelRegister.remove(ctx.channel());
    }
}
